<template>
  <div class="container">
    <!-- 左侧的图表 -->
    <div ref="chart" class="chart"></div>

    <!-- 右侧的按钮列 -->
    <div class="button-column">
      <el-button size="large" @click="restore">恢复初始地图</el-button>
      <el-button size="large" @click="finish">保存地图</el-button>

      <el-button size="large"  @click="setObstacle">{{ dragEnableStr }}</el-button>
      <el-button size="large" @click="undo">撤销</el-button>
    </div>

    <!-- 弹窗 -->
    <el-dialog v-model="dialogVisible" title="输入值" width="50%" @opened="focusInput">
      <el-input
          ref="inputRef"
          v-model="inputValue"
          placeholder="请输入值"
          @keyup.enter="confirmInput"
      ></el-input>
      <template #footer>
        <el-button @click="setStart">设为起点</el-button>
        <el-button @click="setEnd">设为终点</el-button>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="confirmInput">确认</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import * as echarts from 'echarts';
import {ElMessage, ElMessageBox} from 'element-plus';
import {nextTick, onMounted, onUnmounted, ref} from 'vue';
import axios from "axios";
import {func} from "vue-types";
import {log} from "echarts/types/src/util/log";

const inputRef = ref(null); // 创建一个 ref 用于引用 el-input 组件

const gridSize: number = 10; // 网格大小 (10x10)
//[x, y,color locationCode, value]
const gridData = ref<Array<{ value: [number, number, number, string, number] }>>([]);

const chart = ref<HTMLElement | null>(null);
let chartInstance: echarts.ECharts | null = null;
const currentColorValue = ref<number>(1); // 当前选择的颜色对应的值
const inputValue = ref<string>(''); // 输入框的值

const dialogVisible = ref(false); // 控制弹窗显示
let clickedIndex: number | null = null; // 点击的单元格索引
let isDragging = false; // 是否正在拖动
let isDragEnabled = false; // 是否启用拖拽功能
let dragEnableStr = ref<string>('开始设置障碍物')

// 网格数据的 API 地址
const INIT_GRID_DATA_URL = 'http://localhost:8005/route/initMap';
const GET_GRID_DATA_URL = 'http://localhost:8005/route/getLocationMap';
const RESTORE_GRID_DATA_URL = 'http://localhost:8005/route/restore';
const history = ref<Array<Array<{ value: [number, number, number, string] }>>>([]); // 历史记录


onMounted(() => {
  console.log("onMounted...")
  //initializeGrid();
  fetchGridData();

});
const focusInput = () => {
  nextTick(() => {
    inputRef.value.focus();
  });
};


onUnmounted(() => {
  console.log("onUnmounted...")

});

function setStart() {
  updateMap('起点', 1);


}

function setEnd() {
  updateMap('终点', 1)

}

async function fetchGridData() {
  try {
    const response = await axios.get(GET_GRID_DATA_URL);
    const {code, data} = response.data;
    console.log(data);
    // 将后端数据转换为前端格式
    if (code == 200) {
      gridData.value = data.coordinate.map((item: any) => ({
        value: [item.x, item.y, item.color, item.locationCode || '', item.value], // [x, y,color locationCode, value]
      }));

      console.log('Fetched grid data:', gridData.value);
    } else if (code == 201) {
      initializeGrid();
    }
    renderChart();


  } catch (error) {
    console.error('Failed to fetch grid data:', error);
    ElMessage({
      message: '加载地图数据失败，请稍后重试！',
      type: 'error',
    });
  }
}

function initializeGrid() {
  gridData.value = Array.from({length: gridSize}, (_, rowIndex) =>
      Array.from({length: gridSize}, (_, colIndex) => ({
        value: [colIndex, rowIndex, 0, '', 1], // [x, y, color,locationCode,value]
      }))
  ).flat();
  console.log(gridData.value)
}

function setObstacle() {
  if (isDragEnabled) {
    isDragEnabled = false;
    dragEnableStr.value = "开始设置障碍物"
    ElMessage({
      message: '停止设置障碍物',
      type: 'success',
    });
  } else {
    isDragEnabled = true;
    dragEnableStr.value = "停止设置障碍物"

    ElMessage({
      message: '开始设置障碍物',
      type: 'success',
    });
  }


}

async function restore() {
  await ElMessageBox.confirm('确定要初始化地图吗？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  });
  await axios.post(RESTORE_GRID_DATA_URL, {
    headers: {
      'Content-Type': 'application/json; charset=utf-8'
    }
  })
      .then(({data: {code, msg}}) => {
        console.log('code:', code);
        console.log('msg:', msg);
        if (code === 200) {
          console.log('网格数据更新成功');
        } else {
          console.log('网格数据更新失败');
        }
      })
  await fetchGridData()

  ElMessage({
    message: '地图还原成功！',
    type: 'success',
  });
}


function renderChart() {
  if (!chart.value) {

    return;
  }

  chartInstance = echarts.init(chart.value);
  const chartData = gridData.value.map((cell) => [cell.value[0], cell.value[1], cell.value[2]]);
  const option = {
    tooltip: {
      show: false,
    },
    xAxis: {
      type: 'category',
      data: Array.from({length: gridSize}, (_, i) => i),
      show: false,
      splitArea: {show: true},
    },
    yAxis: {
      type: 'category',
      data: Array.from({length: gridSize}, (_, i) => i),
      show: false,
      splitArea: {show: true},
    },
    grid: {
      left: '10%',
      right: '10%',
      top: '10%',
      bottom: '10%',
      containLabel: true,
    },
    visualMap: {
      type: 'piecewise', // 连续型
      min: 0,
      max: 4,
      calculable: true,
      orient: 'horizontal',
      left: 'center',
      bottom: '15%',
      show: false,
      pieces: [
        {value: 0, color: 'grey'},
        {value: 1, color: 'cyan'},
        {value: 2, color: 'orange'},
        {value: 3, color: 'blue'},
        {value: 4, color: 'yellow'}
      ],
    },
    series: [
      {
        type: 'heatmap',
        data: chartData.map((cell) => cell),
        label: {
          show: true,
          formatter: (params: any) => {
            const cell = gridData.value[params.dataIndex];
            return cell.value[3]; // 显示 label
          },
          color: 'black', // 标签颜色
          fontSize: 16, // 标签字体大小
        },
        emphasis: {
          itemStyle: {
            shadowBlur: 10,
            shadowColor: 'rgba(58,54,54,0.5)',
          },
        },
      },
    ],
  };

  chartInstance.setOption(option);
  chartInstance.on('click', (params) => {
    //toggleCell(params.dataIndex);

    handleCellClick(params.dataIndex);
  });
  chartInstance.getZr().on('mousedown', () => {
    console.log("isDragging", isDragging)
    isDragging = true;
    if (isDragEnabled) {
      isDragging = true;
    }
  });

  chartInstance.getZr().on('mouseup', () => {

    console.log("isDragging", isDragging)

    isDragging = false;

  });

  chartInstance.getZr().on('mousemove', (event) => {
    if (isDragging && isDragEnabled && chartInstance) {
      // 获取鼠标位置对应的格子
      const pointInPixel = [event.offsetX, event.offsetY];
      const pointInGrid = chartInstance.convertFromPixel('grid', pointInPixel);

      if (pointInGrid) {
        const x = Math.floor(pointInGrid[0]);
        const y = Math.floor(pointInGrid[1]);

        // 确保坐标在网格范围内
        if (x >= 0 && x < gridSize && y >= 0 && y < gridSize) {
          const dataIndex = y * gridSize + x;
          const cell = gridData.value[dataIndex];

          // 更新格子颜色
          cell.value[2] = 2;
          cell.value[3] = "障碍";
          cell.value[4] = 0;
          // 重新渲染图表
          chartInstance.setOption({
            series: [
              {
                data: gridData.value.map((cell) => [cell.value[0], cell.value[1], cell.value[2]]),
              },
            ],
          });
          console.log(gridData.value)
        }

      }

    }
  });
  chartInstance.getZr().on('contextmenu', (event) => {
    event.event.preventDefault(); // 阻止默认的右击菜单

    if (chartInstance) {
      // 获取鼠标位置对应的格子
      const pointInPixel = [event.offsetX, event.offsetY];
      const pointInGrid = chartInstance.convertFromPixel('grid', pointInPixel);

      if (pointInGrid) {
        const x = Math.floor(pointInGrid[0]);
        const y = Math.floor(pointInGrid[1]);

        // 确保坐标在网格范围内
        if (x >= 0 && x < gridSize && y >= 0 && y < gridSize) {
          const dataIndex = y * gridSize + x;
          const cell = gridData.value[dataIndex];

          // 如果该单元格有数据，则弹出确认删除弹窗
          if (cell.value[3]) {
            ElMessageBox.confirm('确定要删除该点位信息吗？', '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning',
            })
                .then(() => {
                  // 用户确认删除
                  deleteCell(dataIndex);
                })
                .catch(() => {
                  // 用户取消删除
                  ElMessage({
                    message: '已取消删除',
                    type: 'info',
                  });
                });
          } else {
            ElMessage({
              message: '该点位没有信息',
              type: 'info',
            });
          }
        }
      }
    }
  });
}

function deleteCell(dataIndex: number) {


  // 重置单元格的值
  gridData.value[dataIndex].value[2] = 0; // 重置颜色值
  gridData.value[dataIndex].value[3] = ''; // 清空 label
  gridData.value[dataIndex].value[4] = 1;

  // 重新渲染图表
  if (chartInstance) {
    chartInstance.setOption({
      series: [
        {
          data: gridData.value.map((cell) => [cell.value[0], cell.value[1], cell.value[2]]),
        },
      ],
    });
  }

  ElMessage({
    message: '点位信息已删除',
    type: 'success',
  });
}

function handleCellClick(dataIndex: number) {
  clickedIndex = dataIndex;
  console.log(" dataIndex", dataIndex)
  dialogVisible.value = true; // 显示弹窗
}

function confirmInput() {
  saveHistory();
  updateMap(inputValue.value, 0)
}

function updateMap(inputVal: string, val2: number) {
  console.log("clickedIndex", clickedIndex)

  console.log("inputValue.value", inputVal)
// 更新 gridData 中的值
  const cell = gridData.value[clickedIndex];
  cell.value[4] = currentColorValue.value; // 设置为当前选择的颜色对应的值
  gridData.value[clickedIndex].value[2] = currentColorValue.value;
  gridData.value[clickedIndex].value[3] = inputVal;
  gridData.value[clickedIndex].value[4] = val2;
  const chartData = gridData.value.map((cell) => [cell.value[0], cell.value[1], cell.value[2]]);

  // 重新渲染图表
  if (chartInstance) {
    chartInstance.setOption({
      series: [
        {
          data: chartData.map((x) => x),
        },
      ],
    });
    dialogVisible.value = false; // 关闭弹窗
    inputValue.value = ''; // 清空输入框
    console.log('gridData.value', gridData.value);

  }
}


function transform(data: object) {
  let transformed = {
    "coordinate": [],

  };

  data.forEach(function (item) {
    let values = item.value;
    // 假设values数组总是有三个元素，分别对应x, y和value
    transformed.coordinate.push({
      "x": values[0],
      "y": values[1],
      "color": values[2],
      "locationCode": values[3],
      "value": values[4]
    });
  });


  return transformed;
}

function saveHistory() {
  history.value.push(JSON.parse(JSON.stringify(gridData.value)));
}



function undo() {
  if (history.value.length > 0) {
    const lastState = history.value.pop(); // 获取上一次的状态
    if (lastState) {
      gridData.value = JSON.parse(JSON.stringify(lastState)); // 恢复状态

      // 重新渲染图表
      if (chartInstance) {
        chartInstance.setOption({
          series: [
            {
              data: gridData.value.map((cell) => [cell.value[0], cell.value[1], cell.value[2]]),
            },
          ],
        });
      }
    }
  } else {
    ElMessage({
      message: '没有可撤销的操作',
      type: 'info',
    });
  }
}


async function finish() {
  // 显示确认弹窗
  await ElMessageBox.confirm('确定要保存地图吗？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  });
  let transformedData = transform(gridData.value);
  let json = JSON.stringify(transformedData);
  try {
    await axios.post(INIT_GRID_DATA_URL, json, {
      headers: {
        'Content-Type': 'application/json; charset=utf-8'
      }
    })
        .then(({data: {code, msg}}) => {
          console.log('code:', code);
          console.log('msg:', msg);
          if (code === 200) {
            console.log('网格数据更新成功');
          } else {
            console.log('网格数据更新失败');

          }
        })
    console.log('初始化数据已发送');
    ElMessage({
      message: '地图保存成功！',
      type: 'success',
    });
  } catch (error) {
    // 保存失败
    ElMessage({
      message: '保存地图失败:',
      type: 'error',
    });
  }
  console.log("gridDataJson", json);
  history.value.splice(0, history.value.length);
}

</script>

<style scoped>
.container {
  display: flex;
  align-items: flex-start;
  gap: 20px;
}

.chart {
  width: 1000px;
  height: 1000px;
  flex-shrink: 0;
}

.button-column {
  margin-top: 100px;
  display: flex;
  flex-direction: column;
  gap: 40px;
}
.button-column .el-button {
  margin: 0;
  padding: 10px 20px;
  width: 140px;
  height: 130px;
  text-align: center;
  white-space: nowrap;
  font-size: large;
}

</style>